<template>
    <Teleport to="body">
        <div class="_popup_container" v-show="popupShow" v-if="keepAlive || popupShow">
            <div class="_popup_mask" @click="clickMask" v-if="popupShow"></div>
            <div class="_popup" :class="flag ? 'in' : 'out'">
                <slot></slot>
            </div>
        </div>
    </Teleport>
</template>

<script lang="ts" setup>
import { ref, watch, defineProps, defineEmits, defineExpose } from "vue"

const props = defineProps(["show", "keepAlive", "maskClose"])
const emit = defineEmits(["close"])
const popupShow = ref(false)
const flag = ref(false)

watch(
    () => props.show,
    (val) => {
        if (val) show()
        else closePopup()
    }
)

const show = () => {
    flag.value = true
    popupShow.value = true
}

const closePopup = () => {
    flag.value = false
    setTimeout(() => {
        popupShow.value = false
        emit("close")
    }, 300)
}

const clickMask = () => {
    if (props.maskClose) closePopup()
}

defineExpose({
    show,
    closePopup,
})
</script>

<style lang="scss" scoped>
._popup_container {
    width: 100vw;
    height: 100vh;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 999;
    display: flex;
    justify-content: center;
    align-items: center;

    ._popup_mask {
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        z-index: 1000;
        position: absolute;
        top: 0;
        left: 0;
    }

    ._popup {
        z-index: 1001;
        &.in {
            animation: popup_in 0.2s ease forwards;
            @keyframes popup_in {
                0% {
                    transform: scale(0);
                    opacity: 0;
                }
                90% {
                    transform: scale(1.05);
                }
                100% {
                    transform: scale(1);
                    opacity: 1;
                }
            }
        }
        &.out {
            animation: popup_out 0.3s ease forwards;
            @keyframes popup_out {
                0% {
                    transform: scale(1);
                    opacity: 1;
                }
                20% {
                    transform: scale(1.1);
                }
                100% {
                    transform: scale(0.5);
                    opacity: 0;
                }
            }
        }
    }
}
</style>
